using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace EuropeEngulfed.NET
{
    partial class CombatDialog : Form
    {
        private int GAPFORLISTVIEWS = 10;
        Random r;
        bool shownForAttacker;
        bool assault;
        MapInfo.RegionID battleRegion;
        GameState.Weather battleWeather;
        GameController.playerType attacker;
        private struct DieResult
        {
            public int dieRoll;
            public bool hasHit;
        };
        private class BlockInfo
        {
            public bool groundSupported;
            public bool hasFired;
            public Block block;
            public List<DieResult> dieRolls;
            public int hittingOn;
            public BlockInfo(Block block, bool hasFired, bool groundSupported)
            {
                this.block = block;
                this.groundSupported = groundSupported;
                this.hasFired = hasFired;
                dieRolls = new List<DieResult>();
                hittingOn = 6;
            }
            public string hitSummaryToolTip;
        };

        private List<BlockInfo> attackerBlockList;
        private List<GroundSupportUnit> attackerGSUList;
        private List<BlockInfo> defenderBlockList;
        private List<GroundSupportUnit> defenderGSUList;
        private List<BlockInfo> armorHittingOn1;
        private List<BlockInfo> armorHittingOn2;
        private List<BlockInfo> armorHittingOn3;
        private List<BlockInfo> armorHittingOn4;
        private List<BlockInfo> armorHittingOn5;
        private List<BlockInfo> armorHittingOn6;
        private List<BlockInfo> infantryHittingOn1;
        private List<BlockInfo> infantryHittingOn2;
        private List<BlockInfo> infantryHittingOn3;
        private List<BlockInfo> infantryHittingOn4;
        private List<BlockInfo> infantryHittingOn5;
        private List<BlockInfo> infantryHittingOn6;

        private List<Block> nonActiveArmorList;
        private List<Block> nonActiveInfantryList;
        private int numArmorHits;
        private int numInfantryHits;
        private BlockInfo contextBlockInfo;
        private bool armorHittingArmor = false;
        private bool armorHittingInfantry = false;
        private bool infantryHittingArmor = false;
        private bool infantryHittingInfantry = false;
        private Bitmap hitImage;
        private bool counterAttack;
        private bool italianMoraleHasCollapsed;
        private LandRegionState.NewBattleStatus newBattleStatus;

        public int InfantryHits
        {
            get
            {
                return numInfantryHits;
            }
        }

        public int ArmorHits
        {
            get
            {
                return numArmorHits;
            }
        }

        public CombatDialog(IGameStateInfoProvider gameInfoProvider, MapInfo.RegionID battleRegion, bool shownForAttacker, GameController.playerType attacker, bool assault, Dictionary<MapInfo.CountryID, int> attackingGSUSelections, Dictionary<MapInfo.CountryID, int> defendingGSUSelections, bool counterAttack, Random r) : this(gameInfoProvider,battleRegion,shownForAttacker,attacker,assault,attackingGSUSelections,defendingGSUSelections,counterAttack, null, r)
        {

        }

        public CombatDialog(IGameStateInfoProvider gameInfoProvider, MapInfo.RegionID battleRegion, bool shownForAttacker, GameController.playerType attacker, bool assault, Dictionary<MapInfo.CountryID, int> attackingGSUSelections, Dictionary<MapInfo.CountryID, int> defendingGSUSelections, bool counterAttack, List<MapInfo.CountryID> countriesSpendingSAInBattle, Random r)
        {
            InitializeComponent();
            this.shownForAttacker = shownForAttacker;
            this.assault = assault;
            this.battleRegion = battleRegion;
            this.battleWeather = gameInfoProvider.GetCurrentWeatherAtRegion(battleRegion);
            this.counterAttack = counterAttack;
            this.italianMoraleHasCollapsed = gameInfoProvider.ItalianMoraleHasCollapsed();
            this.newBattleStatus = gameInfoProvider.GetNewBattleStatus(battleRegion);
            this.battleIcons.SetBattleIcons(gameInfoProvider, battleRegion, counterAttack);
            this.attacker = attacker;
            this.r = r;
            System.Reflection.Assembly thisExe = System.Reflection.Assembly.GetExecutingAssembly();
            System.IO.Stream file = thisExe.GetManifestResourceStream("EuropeEngulfed.NET.Resources.Hits.bmp");
            hitImage = (Bitmap)Bitmap.FromStream(file);
            attackerBlockList = new List<BlockInfo>();
            attackerGSUList = new List<GroundSupportUnit>();
            defenderBlockList = new List<BlockInfo>();
            defenderGSUList = new List<GroundSupportUnit>();
            nonActiveArmorList = new List<Block>();
            nonActiveInfantryList = new List<Block>();
            armorHittingOn1 = new List<BlockInfo>();
            armorHittingOn2 = new List<BlockInfo>();
            armorHittingOn3 = new List<BlockInfo>();
            armorHittingOn4 = new List<BlockInfo>();
            armorHittingOn5 = new List<BlockInfo>();
            armorHittingOn6 = new List<BlockInfo>();
            infantryHittingOn1 = new List<BlockInfo>();
            infantryHittingOn2 = new List<BlockInfo>();
            infantryHittingOn3 = new List<BlockInfo>();
            infantryHittingOn4 = new List<BlockInfo>();
            infantryHittingOn5 = new List<BlockInfo>();
            infantryHittingOn6 = new List<BlockInfo>();
            numArmorHits = 0;
            numInfantryHits = 0;

            if(assault)
                this.Text = "Assault Battle in " + Enum.GetName(battleRegion.GetType(), battleRegion);
            else
                this.Text = "Battle in " + Enum.GetName(battleRegion.GetType(), battleRegion);

            if (shownForAttacker)
                this.eyeButton.Visible = false;

            if (attacker == GameController.playerType.AlliedPlayer)
            {
                foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                {
                    bool addBlock = false;
                    if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                    {
                        if (countriesSpendingSAInBattle.Contains(block.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && block.CountryOwner == MapInfo.CountryID.FreeFrance) || (MapInfo.IsAxisMinorPower(block.CountryOwner) && countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany)))
                            addBlock = true;
                    }
                    else
                        addBlock = true;
                    if(addBlock)
                    {
                        attackerBlockList.Add(new BlockInfo(block.Copy(), false, false));
                        if (!shownForAttacker)
                        {
                            if (block.IsArmorClass())
                                nonActiveArmorList.Add(block);
                            else
                                nonActiveInfantryList.Add(block);
                        }
                    }
                }

                if (attackingGSUSelections != null)
                {
                    Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                    bool enemyGSUPresent = defendingGSUSelections != null;
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                    {
                        bool addGSU = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(GSU.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && GSU.CountryOwner == MapInfo.CountryID.FreeFrance))
                                addGSU = true;
                        }
                        else
                            addGSU = true;

                        if(addGSU)
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                            else if(!enemyGSUPresent)
                            {
                                attackerGSUList.Add(GSU.Copy());
                            }
                        }
                    }
                }
                else
                {
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                    {
                        bool addGSU = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(GSU.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && GSU.CountryOwner == MapInfo.CountryID.FreeFrance))
                                addGSU = true;
                        }
                        else
                            addGSU = true;

                        if(addGSU)
                        {
                            if (!GSU.OutOfSupply)
                                attackerGSUList.Add(GSU.Copy());
                        }
                    }
                }

                foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                {
                    defenderBlockList.Add(new BlockInfo(block.Copy(), false, false));
                    if (shownForAttacker)
                    {
                        if (block.IsArmorClass())
                            nonActiveArmorList.Add(block);
                        else
                            nonActiveInfantryList.Add(block);
                    }
                }

                if (defendingGSUSelections != null)
                {
                    Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                    bool enemyGSUPresent = attackingGSUSelections != null;
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                    {
                        if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                        {
                            if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                            {
                                defenderGSUList.Add(GSU.Copy());
                                defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                            }
                        }
                        else if(!enemyGSUPresent)
                        {
                            defenderGSUList.Add(GSU.Copy());
                        }
                    }
                }
                else
                {
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                    {
                        if (!GSU.OutOfSupply)
                            defenderGSUList.Add(GSU.Copy());
                    }
                }
            }
            else
            {
                foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                {
                    defenderBlockList.Add(new BlockInfo(block.Copy(), false, false));
                    if (shownForAttacker)
                    {
                        if (block.IsArmorClass())
                            nonActiveArmorList.Add(block);
                        else
                            nonActiveInfantryList.Add(block);
                    }
                }

                if (attackingGSUSelections != null)
                {
                    Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                    bool enemyGSUPresent = defendingGSUSelections != null;
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                    {
                        bool addGSU = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if ((GSU.CountryOwner == MapInfo.CountryID.Italy && countriesSpendingSAInBattle.Contains(GSU.CountryOwner)) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany) && GSU.CountryOwner != MapInfo.CountryID.Italy))
                                addGSU = true;
                        }
                        else
                            addGSU = true;

                        if(addGSU)
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                            else if(!enemyGSUPresent)
                            {
                                attackerGSUList.Add(GSU.Copy());
                            }
                        }
                    }
                }
                else
                {
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                    {
                        if (!GSU.OutOfSupply)
                            attackerGSUList.Add(GSU.Copy());
                    }
                }

                foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                {
                    bool addBlock = false;
                    if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                    {
                        if ((block.CountryOwner == MapInfo.CountryID.Italy && countriesSpendingSAInBattle.Contains(block.CountryOwner)) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany) && block.CountryOwner != MapInfo.CountryID.Italy))
                            addBlock = true;
                    }
                    else
                        addBlock = true;

                    if(addBlock)
                    {
                        attackerBlockList.Add(new BlockInfo(block.Copy(), false, false));
                        if (!shownForAttacker)
                        {
                            if (block.IsArmorClass())
                                nonActiveArmorList.Add(block);
                            else
                                nonActiveInfantryList.Add(block);
                        }
                    }
                }

                if (defendingGSUSelections != null)
                {
                    Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                    bool enemyGSUPresent = attackingGSUSelections != null;
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                    {
                        if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                        {
                            if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                            {
                                defenderGSUList.Add(GSU.Copy());
                                defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                            }
                        }
                        else if(!enemyGSUPresent)
                            defenderGSUList.Add(GSU.Copy());
                    }
                }
                else
                {
                    foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                    {
                        if (!GSU.OutOfSupply)
                            defenderGSUList.Add(GSU.Copy());
                    }
                }
            }

            this.attackerGSUListView.View = View.Tile;
            this.attackerGSUListView.TileSize = new Size(PlayingPieceGraphics.GetGSUSize().Width + PlayingPieceGraphics.GetGSUSize().Width / 3, PlayingPieceGraphics.GetGSUSize().Height + PlayingPieceGraphics.GetGSUSize().Height / 3);
            foreach (GroundSupportUnit attackingGSU in attackerGSUList)
            {
                this.attackerGSUListView.Items.Add(attackingGSU.GetDescription());
            }

            this.defenderGSUListView.View = View.Tile;
            this.defenderGSUListView.TileSize = new Size(PlayingPieceGraphics.GetGSUSize().Width + PlayingPieceGraphics.GetGSUSize().Width / 3, PlayingPieceGraphics.GetGSUSize().Height + PlayingPieceGraphics.GetGSUSize().Height / 3);
            foreach (GroundSupportUnit defendingGSU in defenderGSUList)
            {
                this.defenderGSUListView.Items.Add(defendingGSU.GetDescription());
            }

            #region Add Non-Active group box lists
            this.SuspendLayout();
            ListView nonActiveArmorListView = new ListView();
            ListView nonActiveInfantryListView = new ListView();

            nonActiveArmorListView.BackColor = System.Drawing.SystemColors.ControlDarkDark;
            nonActiveArmorListView.BorderStyle = System.Windows.Forms.BorderStyle.None;
            nonActiveArmorListView.Location = new System.Drawing.Point(2, GAPFORLISTVIEWS);
            nonActiveArmorListView.Name = "nonActiveArmorListView";
            nonActiveArmorListView.OwnerDraw = true;
            nonActiveArmorListView.Size = new System.Drawing.Size(this.attackingArmorGroupBox.Size.Width - nonActiveArmorListView.Location.X * 2, this.attackingArmorGroupBox.Size.Height - nonActiveArmorListView.Location.Y * 2);
            nonActiveArmorListView.TabIndex = 50;
            nonActiveArmorListView.UseCompatibleStateImageBehavior = false;
            nonActiveArmorListView.DrawItem += new DrawListViewItemEventHandler(nonActiveArmorListView_DrawItem);

            nonActiveInfantryListView.BackColor = System.Drawing.SystemColors.ControlDarkDark;
            nonActiveInfantryListView.BorderStyle = System.Windows.Forms.BorderStyle.None;
            nonActiveInfantryListView.Location = new System.Drawing.Point(2, GAPFORLISTVIEWS);
            nonActiveInfantryListView.Name = "nonActiveInfantryListView";
            nonActiveInfantryListView.OwnerDraw = true;
            nonActiveInfantryListView.Size = new System.Drawing.Size(this.attackingArmorGroupBox.Size.Width - nonActiveArmorListView.Location.X * 2, this.attackingArmorGroupBox.Size.Height - nonActiveArmorListView.Location.Y * 2);
            nonActiveInfantryListView.TabIndex = 50;
            nonActiveInfantryListView.UseCompatibleStateImageBehavior = false;
            nonActiveInfantryListView.DrawItem += new DrawListViewItemEventHandler(nonActiveInfantryListView_DrawItem);

            if(shownForAttacker)
            {
                this.defendingArmorGroupBox.Controls.Add(nonActiveArmorListView);
                this.defendingInfantryGroupBox.Controls.Add(nonActiveInfantryListView);
            }
            else
            {
                this.attackingArmorGroupBox.Controls.Add(nonActiveArmorListView);
                this.attackingInfantryGroupBox.Controls.Add(nonActiveInfantryListView);
            }

            nonActiveArmorListView.View = View.Tile;
            nonActiveArmorListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
            foreach (Block armorBlock in nonActiveArmorList)
            {
                nonActiveArmorListView.Items.Add(armorBlock.GetDescription());
            }

            nonActiveInfantryListView.View = View.Tile;
            nonActiveInfantryListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
            foreach (Block infantryBlock in nonActiveInfantryList)
            {
                nonActiveInfantryListView.Items.Add(infantryBlock.GetDescription());
            }

            this.ResumeLayout(false);
            this.PerformLayout();
            #endregion

            /*Additionally,
            any armored units that entered the area directly through the German
            or Belgian border may not fire in the initial round of combat, but they
            may be fired upon normally*/
            //TODO this is not fully implemented, have to somehow 'remember' if an armor unit entered directly from Belgium or not
            if(this.battleIcons.Maginot && shownForAttacker)
            {
                foreach (BlockInfo blockInfo in attackerBlockList)
                {
                    if (blockInfo.block.IsArmorClass())
                        blockInfo.hasFired = true;
                }
            }

            SetupBlocksByHittingPowerAndClass();
        }

        void nonActiveInfantryListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveInfantryList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        void nonActiveArmorListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveArmorList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        private int tabIndex = 51;
        private void SetupActiveListView(ListView listViewToSetup, string name, Point location, Size size,List<BlockInfo> listOfBlockInfo, bool setupDieRolls)
        {
            listViewToSetup.BackColor = System.Drawing.SystemColors.ControlDarkDark;
            listViewToSetup.BorderStyle = System.Windows.Forms.BorderStyle.None;
            listViewToSetup.Location = location;
            listViewToSetup.Name = name;
            listViewToSetup.OwnerDraw = true;
            listViewToSetup.Size = size;
            listViewToSetup.TabIndex = tabIndex;
            tabIndex++;
            listViewToSetup.UseCompatibleStateImageBehavior = false;
            listViewToSetup.View = View.Tile;
            if(setupDieRolls)
            {
                listViewToSetup.TileSize = new Size(PlayingPieceGraphics.GetDieSize().Width + PlayingPieceGraphics.GetDieSize().Width / 3, PlayingPieceGraphics.GetDieSize().Height + PlayingPieceGraphics.GetDieSize().Height / 3);
                foreach(BlockInfo blockInfo in listOfBlockInfo)
                {
                    foreach(DieResult result in blockInfo.dieRolls)
                    {
                        if(result.hasHit)
                            listViewToSetup.Items.Add(result.dieRoll.ToString() + " Hits");
                        else
                            listViewToSetup.Items.Add(result.dieRoll.ToString() + " Miss");
                    }
                }
            }
            else
            {
                listViewToSetup.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (BlockInfo blockInfo in listOfBlockInfo)
                {
                    listViewToSetup.Items.Add(blockInfo.block.GetDescription() + blockInfo.hitSummaryToolTip);
                }
            }
        }

        private void SetupBlocksByHittingPowerAndClass()
        {
            bool anyEnemyInfantryLeft = true;
            bool anyEnemyArmorLeft = true;
            GroupBox activeArmorGroupBox = shownForAttacker ? this.attackingArmorGroupBox : this.defendingArmorGroupBox;
            GroupBox activeInfantryGroupBox = shownForAttacker ? this.attackingInfantryGroupBox : this.defendingInfantryGroupBox;

            #region Allocating blocks to appropriate list by power and class
            armorHittingOn1.Clear();
            armorHittingOn2.Clear();
            armorHittingOn3.Clear();
            armorHittingOn4.Clear();
            armorHittingOn5.Clear();
            armorHittingOn6.Clear();
            infantryHittingOn1.Clear();
            infantryHittingOn2.Clear();
            infantryHittingOn3.Clear();
            infantryHittingOn4.Clear();
            infantryHittingOn5.Clear();
            infantryHittingOn6.Clear();
            /*  a) Elite Units (see the Glossary) [B]
                b) Defending Inf/Cav in Mud (see 1.13) [D]
                c) Armor vs. Infantry (see 6.29) [B]
                d) Ground Support Unit (see 6.6) [B]
                e) Defending in Rough Terrain (see 6.81) [D]
                f) Defending vs. River/Strait Crossing (6.83) [D]
                g) Maginot Line [x2] (see 6.84) [D]
                h) Fortress [x2] (see 6.85) [D]
                i) Field & Heavy Fortifications (see 6.97) [D]
                j) First Round Defending Against Airborne or Amphibious Assault
                (see 7.21/7.31) [D]
                k) Mixed Axis Minor Powers (see 9.18) [B]
                l) Surprise Attack (optional rule 14.43(b)) [A]*/
            if(shownForAttacker)
            {
                int numArmorSteps = 0;
                int numInfantrySteps = 0;

                foreach (BlockInfo blockInfo in defenderBlockList)
                {
                    if (blockInfo.block.IsArmorClass())
                        numArmorSteps += (int)blockInfo.block.CurrentStrength;
                    else
                        numInfantrySteps += (int)blockInfo.block.CurrentStrength;
                }

                anyEnemyInfantryLeft = numInfantrySteps > this.numInfantryHits;
                anyEnemyArmorLeft = numArmorSteps > this.numArmorHits;

                foreach(BlockInfo blockInfo in attackerBlockList)
                {
                    blockInfo.hitSummaryToolTip = "";
                    if (blockInfo.block.IsArmorClass())
                    {
                        int hitBonuses = 0;
                        //1.13...Armor may
                        //never use any hit-bonuses in mud (attacking or defending), including
                        //the surprise attack bonus (see 14.43(b)) and the elite unit bonus (see
                        //Glossary)
                        if(this.battleWeather != GameState.Weather.Mud)
                        {
                            if (blockInfo.block.getBlockType() == Block.BlockType.eliteArmor)
                            {
                                blockInfo.hitSummaryToolTip += ":Elite Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (!anyEnemyArmorLeft && !battleIcons.Rough && !battleIcons.Fortress && !battleIcons.FieldFortification)
                            {
                                blockInfo.hitSummaryToolTip += ":Armor vs Infantry Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.battleWeather != GameState.Weather.Snow && blockInfo.groundSupported)
                            {
                                blockInfo.hitSummaryToolTip += ":GSU Support Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.attacker == GameController.playerType.AlliedPlayer && this.battleIcons.AxisMinor && !anyEnemyArmorLeft && anyEnemyInfantryLeft)
                            {
                                blockInfo.hitSummaryToolTip += ":Allied vs Mixed Axis Minor Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.counterAttack && (battleIcons.Airborne || battleIcons.Amphibious))
                            {
                                if (battleIcons.Airborne)
                                    blockInfo.hitSummaryToolTip += ":vs Airborne Hit Bonus +1";
                                else if (battleIcons.Amphibious)
                                    blockInfo.hitSummaryToolTip += ":vs Amphibious Hit Bonus +1";
                                hitBonuses++;
                            }
                        }

                        if(hitBonuses > 0 && blockInfo.block.CountryOwner == MapInfo.CountryID.Italy && this.italianMoraleHasCollapsed)
                        {
                            hitBonuses = 0;
                            blockInfo.hitSummaryToolTip = "Italian Morale Collapse - Italian units cannot receive hit bonuses";
                        }

                        switch(hitBonuses)
                        {
                            case 0:
                                armorHittingOn6.Add(blockInfo);
                                break;
                            case 1:
                                armorHittingOn5.Add(blockInfo);
                                break;
                            case 2:
                                armorHittingOn4.Add(blockInfo);
                                break;
                            case 3:
                                armorHittingOn3.Add(blockInfo);
                                break;
                            case 4:
                                armorHittingOn2.Add(blockInfo);
                                break;
                            default:
                                throw new InvalidOperationException("Invalid number of hit bonuses calculated");
                        }
                    }
                    else
                    {
                        int hitBonuses = 0;
                        if (blockInfo.block.getBlockType() == Block.BlockType.eliteInfantry)
                        {
                            blockInfo.hitSummaryToolTip += ":Elite Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.battleWeather != GameState.Weather.Snow && this.battleWeather != GameState.Weather.Mud && blockInfo.groundSupported)
                        {
                            blockInfo.hitSummaryToolTip += ":GSU Support Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.attacker == GameController.playerType.AlliedPlayer && this.battleIcons.AxisMinor && anyEnemyInfantryLeft)
                        {
                            blockInfo.hitSummaryToolTip += ":Allied vs Mixed Axis Minor Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.counterAttack && (battleIcons.Airborne || battleIcons.Amphibious))
                        {
                            if (battleIcons.Airborne)
                                blockInfo.hitSummaryToolTip += ":vs Airborne Hit Bonus +1";
                            else if (battleIcons.Amphibious)
                                blockInfo.hitSummaryToolTip += ":vs Amphibious Hit Bonus +1";
                            hitBonuses++;
                        }

                        if (hitBonuses > 0 && blockInfo.block.CountryOwner == MapInfo.CountryID.Italy && this.italianMoraleHasCollapsed)
                        {
                            hitBonuses = 0;
                            blockInfo.hitSummaryToolTip = "Italian Morale Collapse - Italian units cannot receive hit bonuses";
                        }

                        switch (hitBonuses)
                        {
                            case 0:
                                infantryHittingOn6.Add(blockInfo);
                                break;
                            case 1:
                                infantryHittingOn5.Add(blockInfo);
                                break;
                            case 2:
                                infantryHittingOn4.Add(blockInfo);
                                break;
                            case 3:
                                infantryHittingOn3.Add(blockInfo);
                                break;
                            default:
                                throw new InvalidOperationException("Invalid number of hit bonuses calculated");
                        }
                    }
                }
            }
            else
            {
                int numArmorSteps = 0;
                int numInfantrySteps = 0;

                foreach (BlockInfo blockInfo in attackerBlockList)
                {
                    if (blockInfo.block.IsArmorClass())
                        numArmorSteps += (int)blockInfo.block.CurrentStrength;
                    else
                        numInfantrySteps += (int)blockInfo.block.CurrentStrength;
                }

                anyEnemyInfantryLeft = numInfantrySteps > this.numInfantryHits;
                anyEnemyArmorLeft = numArmorSteps > this.numArmorHits;

                foreach (BlockInfo blockInfo in defenderBlockList)
                {
                    blockInfo.hitSummaryToolTip = "";
                    if(blockInfo.block.IsArmorClass())
                    {
                        int hitBonuses = 0;
                        //1.13...Armor may
                        //never use any hit-bonuses in mud (attacking or defending), including
                        //the surprise attack bonus (see 14.43(b)) and the elite unit bonus (see
                        //Glossary)
                        if (this.battleWeather != GameState.Weather.Mud)
                        {
                            if (blockInfo.block.getBlockType() == Block.BlockType.eliteArmor)
                            {
                                blockInfo.hitSummaryToolTip += ":Elite Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (!anyEnemyArmorLeft)
                            {
                                blockInfo.hitSummaryToolTip += ":Armor vs Infantry Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.battleWeather != GameState.Weather.Snow && blockInfo.groundSupported)
                            {
                                blockInfo.hitSummaryToolTip += ":GSU Support Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.attacker == GameController.playerType.AxisPlayer && this.battleIcons.AxisMinor && !anyEnemyArmorLeft && anyEnemyInfantryLeft)
                            {
                                blockInfo.hitSummaryToolTip += ":Allied vs Mixed Axis Minor Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.battleIcons.Rough || (this.battleWeather == GameState.Weather.Snow && this.battleIcons.Swamp))
                            {
                                if (this.battleIcons.Rough)
                                    blockInfo.hitSummaryToolTip += ":Defending in Rough Hit Bonus +1";
                                else if (this.battleWeather == GameState.Weather.Snow && this.battleIcons.Swamp)
                                    blockInfo.hitSummaryToolTip += ":vs Defending in Winter Swamp +1";
                                hitBonuses++;
                            }

                            if(!this.counterAttack)
                            {
                                if (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstInfAndArmorBattle
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstArmorBattle && anyEnemyArmorLeft)
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstInfBattle && !anyEnemyArmorLeft)
                                || this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstInfAndArmorBattle
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstArmorBattle && anyEnemyArmorLeft)
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstInfBattle && !anyEnemyArmorLeft))
                                {
                                    blockInfo.hitSummaryToolTip += ":Defending vs River Crossing Hit Bonus +1";
                                    hitBonuses++;
                                }
                            }

                            if (this.battleIcons.Maginot || this.battleIcons.Fortress)
                            {
                                if (this.battleIcons.Maginot)
                                    blockInfo.hitSummaryToolTip += ":Maginot Line Hit Bonus +2";
                                else if (this.battleIcons.Fortress)
                                    blockInfo.hitSummaryToolTip += ":Fortress Hit Bonus +2";
                                hitBonuses += 2;
                            }
                            else if (this.battleIcons.FieldFortification)
                            {
                                blockInfo.hitSummaryToolTip += ":Field Fortification Hit Bonus +1";
                                hitBonuses++;
                            }
                            if (this.battleIcons.Amphibious || this.battleIcons.Airborne)
                            {
                                if (battleIcons.Airborne)
                                    blockInfo.hitSummaryToolTip += ":vs Airborne Hit Bonus +1";
                                else if (battleIcons.Amphibious)
                                    blockInfo.hitSummaryToolTip += ":vs Amphibious Hit Bonus +1";
                                hitBonuses++;
                            }
                        }

                        if (hitBonuses > 0 && blockInfo.block.CountryOwner == MapInfo.CountryID.Italy && this.italianMoraleHasCollapsed)
                        {
                            hitBonuses = 0;
                            blockInfo.hitSummaryToolTip = "Italian Morale Collapse - Italian units cannot receive hit bonuses";
                        }

                        switch (hitBonuses)
                        {
                            case 0:
                                armorHittingOn6.Add(blockInfo);
                                break;
                            case 1:
                                armorHittingOn5.Add(blockInfo);
                                break;
                            case 2:
                                armorHittingOn4.Add(blockInfo);
                                break;
                            case 3:
                                armorHittingOn3.Add(blockInfo);
                                break;
                            case 4:
                                armorHittingOn2.Add(blockInfo);
                                break;
                            case 5:
                            case 6:
                            case 7:
                            case 8:
                            case 9:
                                armorHittingOn1.Add(blockInfo);
                                break;
                            default:
                                throw new InvalidOperationException("Invalid number of hit bonuses calculated");
                        }
                    }
                    else
                    {
                        int hitBonuses = 0;
                        if (blockInfo.block.getBlockType() == Block.BlockType.eliteInfantry)
                        {
                            blockInfo.hitSummaryToolTip += ":Elite Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.battleWeather != GameState.Weather.Snow && this.battleWeather != GameState.Weather.Mud && blockInfo.groundSupported)
                        {
                            blockInfo.hitSummaryToolTip += ":GSU Support Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.attacker == GameController.playerType.AxisPlayer && this.battleIcons.AxisMinor && anyEnemyInfantryLeft)
                        {
                            blockInfo.hitSummaryToolTip += ":Allied vs Mixed Axis Minor Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.battleIcons.Rough || (this.battleWeather == GameState.Weather.Snow && this.battleIcons.Swamp))
                        {
                            if (this.battleIcons.Rough)
                                blockInfo.hitSummaryToolTip += ":Defending in Rough Hit Bonus +1";
                            else if (this.battleWeather == GameState.Weather.Snow && this.battleIcons.Swamp)
                                blockInfo.hitSummaryToolTip += ":vs Defending in Winter Swamp +1";
                            hitBonuses++;
                        }

                        if(!this.counterAttack)
                        {
                            if (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstInfAndArmorBattle
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstArmorBattle && !anyEnemyInfantryLeft)
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newMaginotAndRiverAgainstInfBattle && anyEnemyInfantryLeft)
                                || this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstInfAndArmorBattle
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstArmorBattle && !anyEnemyInfantryLeft)
                                || (this.newBattleStatus == LandRegionState.NewBattleStatus.newRiverCrossingAgainstInfBattle && anyEnemyInfantryLeft))
                            {
                                blockInfo.hitSummaryToolTip += ":Defending vs River Crossing Hit Bonus +1";
                                hitBonuses++;
                            }
                        }

                        if (this.battleIcons.Maginot || this.battleIcons.Fortress)
                        {
                            if (this.battleIcons.Maginot)
                                blockInfo.hitSummaryToolTip += ":Maginot Line Hit Bonus +2";
                            else if (this.battleIcons.Fortress)
                                blockInfo.hitSummaryToolTip += ":Fortress Hit Bonus +2";
                            hitBonuses += 2;
                        }
                        else if (this.battleIcons.FieldFortification)
                        {
                            blockInfo.hitSummaryToolTip += ":Field Fortification Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.battleIcons.Amphibious || this.battleIcons.Airborne)
                        {
                            if (battleIcons.Airborne)
                                blockInfo.hitSummaryToolTip += ":vs Airborne Hit Bonus +1";
                            else if (battleIcons.Amphibious)
                                blockInfo.hitSummaryToolTip += ":vs Amphibious Hit Bonus +1";
                            hitBonuses++;
                        }
                        if (this.battleIcons.Mud)
                        {
                            blockInfo.hitSummaryToolTip += ":Infantry Defending in Mud Hit Bonus +1";
                            hitBonuses++;
                        }

                        if (hitBonuses > 0 && blockInfo.block.CountryOwner == MapInfo.CountryID.Italy && this.italianMoraleHasCollapsed)
                        {
                            hitBonuses = 0;
                            blockInfo.hitSummaryToolTip = "Italian Morale Collapse - Italian units cannot receive hit bonuses";
                        }

                        switch (hitBonuses)
                        {
                            case 0:
                                infantryHittingOn6.Add(blockInfo);
                                break;
                            case 1:
                                infantryHittingOn5.Add(blockInfo);
                                break;
                            case 2:
                                infantryHittingOn4.Add(blockInfo);
                                break;
                            case 3:
                                infantryHittingOn3.Add(blockInfo);
                                break;
                            case 4:
                                infantryHittingOn2.Add(blockInfo);
                                break;
                            case 5:
                            case 6:
                            case 7:
                            case 8:
                            case 9:
                            case 10:
                                infantryHittingOn1.Add(blockInfo);
                                break;
                            default:
                                throw new InvalidOperationException("Invalid number of hit bonuses calculated");
                        }
                    }
                }
            }
            #endregion

            activeInfantryGroupBox.Controls.Clear();
            activeArmorGroupBox.Controls.Clear();

            #region setup active armor group box
            {
                Point ptToPlaceListView = new Point(2,GAPFORLISTVIEWS);
                int heightOfListViews = (activeArmorGroupBox.Height / 2) - GAPFORLISTVIEWS;
                Point ptToPlaceDieRollListView = new Point(2, heightOfListViews + GAPFORLISTVIEWS);
                int listViewWidths = 0;
                int numArmorGroupings = 0;
                
                if (armorHittingOn1.Count > 0)
                    numArmorGroupings++;
                if (armorHittingOn2.Count > 0)
                    numArmorGroupings++;
                if (armorHittingOn3.Count > 0)
                    numArmorGroupings++;
                if (armorHittingOn4.Count > 0)
                    numArmorGroupings++;
                if (armorHittingOn5.Count > 0)
                    numArmorGroupings++;
                if (armorHittingOn6.Count > 0)
                    numArmorGroupings++;
                if (numArmorGroupings > 0)
                    listViewWidths = (activeArmorGroupBox.Width - 4) / numArmorGroupings;
                if (armorHittingOn1.Count > 0)
                {
                    ListView armorHittingOn1ListView = new ListView();
                    ListView armorHittingOn1DieRollsListView = new ListView();
                    PictureBox hittingOn1PictureBox = new PictureBox();
                    hittingOn1PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._1SidedDiceRedSmall;
                    hittingOn1PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn1PictureBox.Name = "hittingOn1PictureBox";
                    hittingOn1PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn1PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn1PictureBox);
                    SetupActiveListView(armorHittingOn1ListView, "armorHittingOn1ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn1, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn1ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn1ListView_DrawItem);
                    armorHittingOn1ListView.MouseClick += new MouseEventHandler(armorHittingOn1ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn1ListView);
                    SetupActiveListView(armorHittingOn1DieRollsListView, "armorHittingOn1DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn1, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn1DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn1DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn1DieRollsListView);
                }
                if (armorHittingOn2.Count > 0)
                {
                    ListView armorHittingOn2ListView = new ListView();
                    ListView armorHittingOn2DieRollsListView = new ListView();
                    PictureBox hittingOn2PictureBox = new PictureBox();
                    hittingOn2PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._2SidedDiceRedSmall;
                    hittingOn2PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn2PictureBox.Name = "hittingOn2PictureBox";
                    hittingOn2PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn2PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn2PictureBox);
                    SetupActiveListView(armorHittingOn2ListView, "armorHittingOn2ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn2, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn2ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn2ListView_DrawItem);
                    armorHittingOn2ListView.MouseClick += new MouseEventHandler(armorHittingOn2ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn2ListView);
                    SetupActiveListView(armorHittingOn2DieRollsListView, "armorHittingOn2DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn2, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn2DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn2DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn2DieRollsListView);
                }
                if (armorHittingOn3.Count > 0)
                {
                    ListView armorHittingOn3ListView = new ListView();
                    ListView armorHittingOn3DieRollsListView = new ListView();
                    PictureBox hittingOn3PictureBox = new PictureBox();
                    hittingOn3PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._3SidedDiceRedSmall;
                    hittingOn3PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn3PictureBox.Name = "hittingOn3PictureBox";
                    hittingOn3PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn3PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn3PictureBox);
                    SetupActiveListView(armorHittingOn3ListView, "armorHittingOn3ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn3, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn3ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn3ListView_DrawItem);
                    armorHittingOn3ListView.MouseClick += new MouseEventHandler(armorHittingOn3ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn3ListView);
                    SetupActiveListView(armorHittingOn3DieRollsListView, "armorHittingOn3DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn3, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn3DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn3DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn3DieRollsListView);
                }
                if (armorHittingOn4.Count > 0)
                {
                    ListView armorHittingOn4ListView = new ListView();
                    ListView armorHittingOn4DieRollsListView = new ListView();
                    PictureBox hittingOn4PictureBox = new PictureBox();
                    hittingOn4PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._4SidedDiceRedSmall;
                    hittingOn4PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn4PictureBox.Name = "hittingOn4PictureBox";
                    hittingOn4PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn4PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn4PictureBox);
                    SetupActiveListView(armorHittingOn4ListView, "armorHittingOn4ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn4, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn4ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn4ListView_DrawItem);
                    armorHittingOn4ListView.MouseClick += new MouseEventHandler(armorHittingOn4ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn4ListView);
                    SetupActiveListView(armorHittingOn4DieRollsListView, "armorHittingOn4DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn4, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn4DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn4DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn4DieRollsListView);
                }
                if (armorHittingOn5.Count > 0)
                {
                    ListView armorHittingOn5ListView = new ListView();
                    ListView armorHittingOn5DieRollsListView = new ListView();
                    PictureBox hittingOn5PictureBox = new PictureBox();
                    hittingOn5PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._5SidedDiceRedSmall;
                    hittingOn5PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn5PictureBox.Name = "hittingOn5PictureBox";
                    hittingOn5PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn5PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn5PictureBox);
                    SetupActiveListView(armorHittingOn5ListView, "armorHittingOn5ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn5, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn5ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn5ListView_DrawItem);
                    armorHittingOn5ListView.MouseClick += new MouseEventHandler(armorHittingOn5ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn5ListView);
                    SetupActiveListView(armorHittingOn5DieRollsListView, "armorHittingOn5DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn5, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn5DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn5DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn5DieRollsListView);
                }
                if (armorHittingOn6.Count > 0)
                {
                    ListView armorHittingOn6ListView = new ListView();
                    ListView armorHittingOn6DieRollsListView = new ListView();
                    PictureBox hittingOn6PictureBox = new PictureBox();
                    hittingOn6PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._6SidedDiceRedSmall;
                    hittingOn6PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn6PictureBox.Name = "hittingOn6PictureBox";
                    hittingOn6PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn6PictureBox.TabStop = false;
                    activeArmorGroupBox.Controls.Add(hittingOn6PictureBox);
                    SetupActiveListView(armorHittingOn6ListView, "armorHittingOn6ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), armorHittingOn6, false);
                    ptToPlaceListView.X += listViewWidths;
                    armorHittingOn6ListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn6ListView_DrawItem);
                    armorHittingOn6ListView.MouseClick += new MouseEventHandler(armorHittingOn6ListView_MouseClick);
                    activeArmorGroupBox.Controls.Add(armorHittingOn6ListView);
                    SetupActiveListView(armorHittingOn6DieRollsListView, "armorHittingOn6DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), armorHittingOn6, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    armorHittingOn6DieRollsListView.DrawItem += new DrawListViewItemEventHandler(armorHittingOn6DieRollsListView_DrawItem);
                    activeArmorGroupBox.Controls.Add(armorHittingOn6DieRollsListView);
                }
            }
            #endregion

            #region setup active infantry group box
            {
                Point ptToPlaceListView = new Point(2, GAPFORLISTVIEWS);
                int heightOfListViews = (activeInfantryGroupBox.Height / 2) - GAPFORLISTVIEWS;
                Point ptToPlaceDieRollListView = new Point(2, heightOfListViews + GAPFORLISTVIEWS);
                int listViewWidths = 0;
                int numInfantryGroupings = 0;

                if (infantryHittingOn1.Count > 0)
                    numInfantryGroupings++;
                if (infantryHittingOn2.Count > 0)
                    numInfantryGroupings++;
                if (infantryHittingOn3.Count > 0)
                    numInfantryGroupings++;
                if (infantryHittingOn4.Count > 0)
                    numInfantryGroupings++;
                if (infantryHittingOn5.Count > 0)
                    numInfantryGroupings++;
                if (infantryHittingOn6.Count > 0)
                    numInfantryGroupings++;

                if (numInfantryGroupings > 0)
                    listViewWidths = (activeInfantryGroupBox.Width - 4) / numInfantryGroupings;

                if (infantryHittingOn1.Count > 0)
                {
                    ListView infantryHittingOn1ListView = new ListView();
                    ListView infantryHittingOn1DieRollsListView = new ListView();
                    PictureBox hittingOn1PictureBox = new PictureBox();
                    hittingOn1PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._1SidedDiceRedSmall;
                    hittingOn1PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn1PictureBox.Name = "hittingOn1PictureBox";
                    hittingOn1PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn1PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn1PictureBox);
                    SetupActiveListView(infantryHittingOn1ListView, "infantryHittingOn1ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn1, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn1ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn1ListView_DrawItem);
                    infantryHittingOn1ListView.MouseClick += new MouseEventHandler(infantryHittingOn1ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn1ListView);
                    SetupActiveListView(infantryHittingOn1DieRollsListView, "infantryHittingOn1DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn1, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn1DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn1DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn1DieRollsListView);
                }
                if (infantryHittingOn2.Count > 0)
                {
                    ListView infantryHittingOn2ListView = new ListView();
                    ListView infantryHittingOn2DieRollsListView = new ListView();
                    PictureBox hittingOn2PictureBox = new PictureBox();
                    hittingOn2PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._2SidedDiceRedSmall;
                    hittingOn2PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn2PictureBox.Name = "hittingOn2PictureBox";
                    hittingOn2PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn2PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn2PictureBox);
                    SetupActiveListView(infantryHittingOn2ListView, "infantryHittingOn2ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn2, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn2ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn2ListView_DrawItem);
                    infantryHittingOn2ListView.MouseClick += new MouseEventHandler(infantryHittingOn2ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn2ListView);
                    SetupActiveListView(infantryHittingOn2DieRollsListView, "infantryHittingOn2DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn2, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn2DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn2DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn2DieRollsListView);
                }
                if (infantryHittingOn3.Count > 0)
                {
                    ListView infantryHittingOn3ListView = new ListView();
                    ListView infantryHittingOn3DieRollsListView = new ListView();
                    PictureBox hittingOn3PictureBox = new PictureBox();
                    hittingOn3PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._3SidedDiceRedSmall;
                    hittingOn3PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn3PictureBox.Name = "hittingOn3PictureBox";
                    hittingOn3PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn3PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn3PictureBox);
                    SetupActiveListView(infantryHittingOn3ListView, "infantryHittingOn3ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn3, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn3ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn3ListView_DrawItem);
                    infantryHittingOn3ListView.MouseClick += new MouseEventHandler(infantryHittingOn3ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn3ListView);
                    SetupActiveListView(infantryHittingOn3DieRollsListView, "infantryHittingOn3DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn3, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn3DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn3DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn3DieRollsListView);
                }
                if (infantryHittingOn4.Count > 0)
                {
                    ListView infantryHittingOn4ListView = new ListView();
                    ListView infantryHittingOn4DieRollsListView = new ListView();
                    PictureBox hittingOn4PictureBox = new PictureBox();
                    hittingOn4PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._4SidedDiceRedSmall;
                    hittingOn4PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn4PictureBox.Name = "hittingOn4PictureBox";
                    hittingOn4PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn4PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn4PictureBox);
                    SetupActiveListView(infantryHittingOn4ListView, "infantryHittingOn4ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn4, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn4ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn4ListView_DrawItem);
                    infantryHittingOn4ListView.MouseClick += new MouseEventHandler(infantryHittingOn4ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn4ListView);
                    SetupActiveListView(infantryHittingOn4DieRollsListView, "infantryHittingOn4DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn4, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn4DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn4DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn4DieRollsListView);
                }
                if (infantryHittingOn5.Count > 0)
                {
                    ListView infantryHittingOn5ListView = new ListView();
                    ListView infantryHittingOn5DieRollsListView = new ListView();
                    PictureBox hittingOn5PictureBox = new PictureBox();
                    hittingOn5PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._5SidedDiceRedSmall;
                    hittingOn5PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn5PictureBox.Name = "hittingOn5PictureBox";
                    hittingOn5PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn5PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn5PictureBox);
                    SetupActiveListView(infantryHittingOn5ListView, "infantryHittingOn5ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn5, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn5ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn5ListView_DrawItem);
                    infantryHittingOn5ListView.MouseClick += new MouseEventHandler(infantryHittingOn5ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn5ListView);
                    SetupActiveListView(infantryHittingOn5DieRollsListView, "infantryHittingOn5DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn5, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn5DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn5DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn5DieRollsListView);
                }
                if (infantryHittingOn6.Count > 0)
                {
                    ListView infantryHittingOn6ListView = new ListView();
                    ListView infantryHittingOn6DieRollsListView = new ListView();
                    PictureBox hittingOn6PictureBox = new PictureBox();
                    hittingOn6PictureBox.Image = global::EuropeEngulfed.NET.Properties.Resources._6SidedDiceRedSmall;
                    hittingOn6PictureBox.Location = new System.Drawing.Point(ptToPlaceListView.X + listViewWidths / 2, 0);
                    hittingOn6PictureBox.Name = "hittingOn6PictureBox";
                    hittingOn6PictureBox.Size = new System.Drawing.Size(10, 10);
                    hittingOn6PictureBox.TabStop = false;
                    activeInfantryGroupBox.Controls.Add(hittingOn6PictureBox);
                    SetupActiveListView(infantryHittingOn6ListView, "infantryHittingOn6ListView", ptToPlaceListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn6, false);
                    ptToPlaceListView.X += listViewWidths;
                    infantryHittingOn6ListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn6ListView_DrawItem);
                    infantryHittingOn6ListView.MouseClick += new MouseEventHandler(infantryHittingOn6ListView_MouseClick);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn6ListView);
                    SetupActiveListView(infantryHittingOn6DieRollsListView, "infantryHittingOn6DieRollsListView", ptToPlaceDieRollListView, new Size(listViewWidths, heightOfListViews), infantryHittingOn6, true);
                    ptToPlaceDieRollListView.X += listViewWidths;
                    infantryHittingOn6DieRollsListView.DrawItem += new DrawListViewItemEventHandler(infantryHittingOn6DieRollsListView_DrawItem);
                    activeInfantryGroupBox.Controls.Add(infantryHittingOn6DieRollsListView);
                }
            }
            #endregion

            #region setup who is hitting whom
            {
                List<BlockInfo> enemyBlockList = shownForAttacker ? defenderBlockList : attackerBlockList;
                List<BlockInfo> friendlyBlockList = shownForAttacker ? attackerBlockList : defenderBlockList;
                int numEnemyArmorSteps = 0;
                int numEnemyInfantrySteps = 0;
                int numFriendlyArmorSteps = 0;
                int numFriendlyInfantrySteps = 0;

                foreach (BlockInfo blockInfo in friendlyBlockList)
                {
                    if (blockInfo.block.IsArmorClass())
                        numFriendlyArmorSteps += (int)blockInfo.block.CurrentStrength;
                    else
                        numFriendlyInfantrySteps += (int)blockInfo.block.CurrentStrength;
                }

                foreach (BlockInfo blockInfo in enemyBlockList)
                {
                    if (blockInfo.block.IsArmorClass())
                        numEnemyArmorSteps += (int)blockInfo.block.CurrentStrength;
                    else
                        numEnemyInfantrySteps += (int)blockInfo.block.CurrentStrength;
                }

                numEnemyArmorSteps -= numArmorHits;
                numEnemyInfantrySteps -= numInfantryHits;

                this.armorHittingArmor = false;
                this.armorHittingInfantry = false;
                this.infantryHittingArmor = false;
                this.infantryHittingInfantry = false;
                if(numFriendlyArmorSteps > 0)
                {
                    if (numEnemyArmorSteps > 0)
                        this.armorHittingArmor = true;
                    else
                        this.armorHittingInfantry = true;
                }

                if(numFriendlyInfantrySteps > 0)
                {
                    if (numEnemyInfantrySteps > 0)
                        this.infantryHittingInfantry = true;
                    else
                        this.infantryHittingArmor = true;
                }

                if(shownForAttacker)
                {
                    this.attakerArmorHitsPictureBox.Visible = false;
                    this.attackerArmorHitsLabel.Visible = false;
                    this.attakerInfantryHitsPictureBox.Visible = false;
                    this.attackerInfantryHitsLabel.Visible = false;

                    this.defenderArmorHitsLabel.Text = numArmorHits.ToString();
                    this.defenderInfantryHitsLabel.Text = numInfantryHits.ToString();
                }
                else
                {
                    this.defenderArmorHitsPictureBox.Visible = false;
                    this.defenderArmorHitsLabel.Visible = false;
                    this.defenderInfantryHitsPictureBox.Visible = false;
                    this.defenderInfantryHitsLabel.Visible = false;

                    this.attackerArmorHitsLabel.Text = numArmorHits.ToString();
                    this.attackerInfantryHitsLabel.Text = numInfantryHits.ToString();
                }
            }
            #endregion
        }

        void infantryHittingOn6ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn6, 6);
        }

        void infantryHittingOn5ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn5, 5);
        }

        void infantryHittingOn4ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn4, 4);
        }

        void infantryHittingOn3ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn3, 3);
        }

        void infantryHittingOn2ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn2, 2);
        }

        void infantryHittingOn1ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, infantryHittingOn1, 1);
        }

        void armorHittingOn6ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, armorHittingOn6, 6);
        }

        void armorHittingOn5ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, armorHittingOn5, 5);
        }

        void armorHittingOn4ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, armorHittingOn4, 4);
        }

        void armorHittingOn3ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, armorHittingOn3, 3);
        }

        void armorHittingOn2ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView)sender, e, armorHittingOn2, 2);
        }

        void armorHittingOn1ListView_MouseClick(object sender, MouseEventArgs e)
        {
            activeBlockList_MouseClick((ListView) sender, e, armorHittingOn1, 1);
        }

        private MapInfo.CountryID GetEquivalentGroundSupportCountry(MapInfo.CountryID country)
        {
            switch(country)
            {
                case MapInfo.CountryID.Bulgaria:
                case MapInfo.CountryID.Hungary:
                case MapInfo.CountryID.Rumania:
                case MapInfo.CountryID.Finland:
                    return MapInfo.CountryID.Germany;
                case MapInfo.CountryID.FreeFrance:
                    return MapInfo.CountryID.USA;
                default:
                    return country;
            }
        }

        private void activeBlockList_MouseClick(ListView activeListView, MouseEventArgs e, List<BlockInfo> activeBlockList, int hittingOn)
        {
            if (e.Button == MouseButtons.Right)
            {
                try
                {
                    int totalGroundSupported = 0;
                    ContextMenu blockListContextMenu = new ContextMenu();
                    bool groundSupportedMenuItemAdded = false;
                    Dictionary<MapInfo.CountryID, int> groundSupportLeftOver = new Dictionary<MapInfo.CountryID, int>();
                    List<BlockInfo> blockInfoListToCheck = shownForAttacker ? attackerBlockList : defenderBlockList;
                    List<GroundSupportUnit> gsuListToCheck = shownForAttacker ? attackerGSUList : defenderGSUList;

                    foreach (GroundSupportUnit gsu in gsuListToCheck)
                    {
                        if (!groundSupportLeftOver.ContainsKey(gsu.CountryOwner))
                            groundSupportLeftOver.Add(gsu.CountryOwner, 1);
                        else
                            groundSupportLeftOver[gsu.CountryOwner]++;
                    }

                    foreach (BlockInfo blockInfo in blockInfoListToCheck)
                    {
                        if (blockInfo.groundSupported)
                        {
                            groundSupportLeftOver[GetEquivalentGroundSupportCountry(blockInfo.block.CountryOwner)]--;
                            totalGroundSupported++;
                        }
                    }

                    if(battleWeather == GameState.Weather.Clear || battleWeather == GameState.Weather.LightMud)
                    {
                        if(activeListView.SelectedItems.Count > 0)
                        {
                            if (groundSupportLeftOver.ContainsKey(GetEquivalentGroundSupportCountry(activeBlockList[activeListView.SelectedItems[0].Index].block.CountryOwner)))
                            {
                                if (!activeBlockList[activeListView.SelectedItems[0].Index].groundSupported && groundSupportLeftOver[GetEquivalentGroundSupportCountry(activeBlockList[activeListView.SelectedItems[0].Index].block.CountryOwner)] > 0 && !activeBlockList[activeListView.SelectedItems[0].Index].hasFired && totalGroundSupported < 3)
                                {
                                    contextBlockInfo = activeBlockList[activeListView.SelectedItems[0].Index];
                                    MenuItem assignGroundSupportMenuItem = new MenuItem("Assign Ground Support");
                                    assignGroundSupportMenuItem.Click += new EventHandler(assignGroundSupportMenuItem_Click);
                                    blockListContextMenu.MenuItems.Add(assignGroundSupportMenuItem);
                                    groundSupportedMenuItemAdded = true;
                                }
                            }
                        }
                    }

                    if (!groundSupportedMenuItemAdded)
                    {
                        if(activeListView.SelectedItems.Count > 0)
                        {
                            if (activeBlockList[activeListView.SelectedItems[0].Index].groundSupported && !activeBlockList[activeListView.SelectedItems[0].Index].hasFired)
                            {
                                contextBlockInfo = activeBlockList[activeListView.SelectedItems[0].Index];
                                MenuItem unAssignGroundSupportMenuItem = new MenuItem("Un-Assign Ground Support");
                                unAssignGroundSupportMenuItem.Click += new EventHandler(unAssignGroundSupportMenuItem_Click);
                                blockListContextMenu.MenuItems.Add(unAssignGroundSupportMenuItem);
                            }
                        }
                    }

                    if (!activeBlockList[activeListView.SelectedItems[0].Index].hasFired)
                    {
                        contextBlockInfo = activeBlockList[activeListView.SelectedItems[0].Index];
                        contextBlockInfo.hittingOn = hittingOn;
                        MenuItem FireUnitMenuItem = new MenuItem("Fire Unit");
                        FireUnitMenuItem.Click += new EventHandler(FireUnitMenuItem_Click);
                        blockListContextMenu.MenuItems.Add(FireUnitMenuItem);
                    }

                    if (blockListContextMenu.MenuItems.Count > 0)
                    {
                        Point ptToShowContextMenu = e.Location;
                        if (shownForAttacker)
                        {
                            if (activeBlockList[activeListView.SelectedItems[0].Index].block.IsArmorClass())
                            {
                                ptToShowContextMenu.X += attackingArmorGroupBox.Location.X;
                                ptToShowContextMenu.Y += attackingArmorGroupBox.Location.Y;
                            }
                            else
                            {
                                ptToShowContextMenu.X += attackingInfantryGroupBox.Location.X;
                                ptToShowContextMenu.Y += attackingInfantryGroupBox.Location.Y;
                            }
                        }
                        else
                        {
                            if (activeBlockList[activeListView.SelectedItems[0].Index].block.IsArmorClass())
                            {
                                ptToShowContextMenu.X += defendingArmorGroupBox.Location.X;
                                ptToShowContextMenu.Y += defendingArmorGroupBox.Location.Y;
                            }
                            else
                            {
                                ptToShowContextMenu.X += defendingInfantryGroupBox.Location.X;
                                ptToShowContextMenu.Y += defendingInfantryGroupBox.Location.Y;
                            }
                        }

                        ptToShowContextMenu.X += activeListView.Location.X;
                        ptToShowContextMenu.Y += activeListView.Location.Y;
                        blockListContextMenu.Show(this, ptToShowContextMenu);
                    }
                }
                catch(IndexOutOfRangeException)
                {

                }
            }
        }

        private void FireUnit(BlockInfo blockInfo, ref double parthit)
        {
            if(!blockInfo.hasFired)
            {
                List<BlockInfo> enemyBlockList = shownForAttacker ? defenderBlockList : attackerBlockList;
                int numEnemyArmorSteps = 0;
                int numEnemyInfantrySteps = 0;
                bool hittingArmor = false;
                bool allUSUnits = true;

                foreach (BlockInfo enemyBlockInfo in enemyBlockList)
                {
                    if (enemyBlockInfo.block.IsArmorClass())
                        numEnemyArmorSteps += (int)enemyBlockInfo.block.CurrentStrength;
                    else
                        numEnemyInfantrySteps += (int)enemyBlockInfo.block.CurrentStrength;

                    if (enemyBlockInfo.block.CountryOwner != MapInfo.CountryID.FreeFrance && enemyBlockInfo.block.CountryOwner != MapInfo.CountryID.USA)
                    {
                        allUSUnits = false;
                    }
                }

                if (blockInfo.block.CountryOwner == MapInfo.CountryID.VichyFrance && allUSUnits)
                {   /*If combat against the Vichy unit is conducted
                    solely by U.S. units, the Vichy unit is always eliminated without defending
                    at the start of the Combat round involving the Vichy unit.*/
                    blockInfo.hasFired = true;
                    return;
                }

                numEnemyArmorSteps -= numArmorHits;
                numEnemyInfantrySteps -= numInfantryHits;

                if (blockInfo.block.IsArmorClass())
                {
                    if (numEnemyArmorSteps > 0)
                        hittingArmor = true;
                    else
                        hittingArmor = false;
                }
                else
                {
                    if (numEnemyInfantrySteps > 0)
                        hittingArmor = false;
                    else
                        hittingArmor = true;
                }

                double dnumDiceThrows = (double)blockInfo.block.CurrentStrength;
                int numDiceThrows;
                if (this.assault)
                    dnumDiceThrows *= 2;
                if (shownForAttacker && battleWeather == GameState.Weather.Snow)
                {
                    LandRegion landRegion = (LandRegion)MapInfo.GetRegion(battleRegion);
                    if(!(landRegion.OriginalCountry == MapInfo.CountryID.USSR && blockInfo.block.CountryOwner == MapInfo.CountryID.USSR)
                        && !(landRegion.OriginalCountry == MapInfo.CountryID.Finland && blockInfo.block.CountryOwner == MapInfo.CountryID.Finland))
                        dnumDiceThrows /= 2;
                }
                else if (shownForAttacker && battleWeather != GameState.Weather.Snow && this.battleIcons.Swamp)
                    dnumDiceThrows /= 2;
                if(blockInfo.block.OutOfSupply)
                    dnumDiceThrows /= 2;
                numDiceThrows = (int)Math.Truncate(dnumDiceThrows);
                parthit += (dnumDiceThrows - numDiceThrows);
                if(parthit >= 1)
                {
                    numDiceThrows++;
                    parthit -= 1;
                }

                for (int i = 0; i < numDiceThrows; i++)
                {
                    DieResult dieResult = new DieResult();
                    dieResult.dieRoll = r.Next(6) + 1;
                    if (dieResult.dieRoll >= blockInfo.hittingOn)
                    {
                        dieResult.hasHit = true;
                        if (hittingArmor)
                        {
                            if (numEnemyArmorSteps > 0)
                            {
                                numArmorHits++;
                                numEnemyArmorSteps--;
                                if (numEnemyArmorSteps <= 0)
                                    hittingArmor = false;
                            }
                        }
                        else
                        {
                            if (numEnemyInfantrySteps > 0)
                            {
                                numInfantryHits++;
                                numEnemyInfantrySteps--;
                                if (numEnemyInfantrySteps <= 0)
                                    hittingArmor = true;
                            }
                        }
                    }
                    else
                        dieResult.hasHit = false;
                    blockInfo.dieRolls.Add(dieResult);
                }
                blockInfo.hasFired = true;
            }
        }

        void FireUnitMenuItem_Click(object sender, EventArgs e)
        {
            double parthit = 0;
            FireUnit(contextBlockInfo, ref parthit);
            SetupBlocksByHittingPowerAndClass();
            this.Invalidate();
        }

        void unAssignGroundSupportMenuItem_Click(object sender, EventArgs e)
        {
            contextBlockInfo.groundSupported = false;
            SetupBlocksByHittingPowerAndClass();
            this.Invalidate();
        }

        void assignGroundSupportMenuItem_Click(object sender, EventArgs e)
        {
            contextBlockInfo.groundSupported = true;
            SetupBlocksByHittingPowerAndClass();
            this.Invalidate();
        }

        void infantryHittingOn6DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach(BlockInfo blockInfo in infantryHittingOn6)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn5DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in infantryHittingOn5)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn4DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in infantryHittingOn4)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn3DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in infantryHittingOn3)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn2DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in infantryHittingOn2)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn1DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in infantryHittingOn1)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn6DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn6)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn5DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn5)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn4DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn4)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn3DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn3)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn2DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn2)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void armorHittingOn1DieRollsListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            int indexToDraw = e.ItemIndex;
            foreach (BlockInfo blockInfo in armorHittingOn1)
            {
                if (indexToDraw < blockInfo.dieRolls.Count)
                {
                    PlayingPieceGraphics.PaintHitDie(e.Graphics, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), blockInfo.dieRolls[indexToDraw].dieRoll, blockInfo.dieRolls[indexToDraw].hasHit);
                    break;
                }
                else
                    indexToDraw -= blockInfo.dieRolls.Count;
            }
        }

        void infantryHittingOn6ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn6[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn6[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn6[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn6[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void infantryHittingOn5ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn5[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn5[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn5[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn5[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void infantryHittingOn4ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn4[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn4[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn4[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn4[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void infantryHittingOn3ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn3[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn3[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn3[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn3[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void infantryHittingOn2ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn2[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn2[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn2[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn2[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void infantryHittingOn1ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, infantryHittingOn1[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (infantryHittingOn1[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, infantryHittingOn1[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (infantryHittingOn1[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn6ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn6[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn6[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn6[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn6[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn5ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn5[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn5[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn5[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn5[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn4ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn4[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn4[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn4[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn4[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn3ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn3[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn3[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn3[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn3[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn2ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn2[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn2[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn2[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn2[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        void armorHittingOn1ListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintBlock(e.Graphics, armorHittingOn1[e.ItemIndex].block, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
            if (armorHittingOn1[e.ItemIndex].groundSupported)
                PlayingPieceGraphics.PaintMiniGSU(e.Graphics, armorHittingOn1[e.ItemIndex].block.CountryOwner, new Point(e.Bounds.Left + 7, e.Bounds.Top + 7));
            if (armorHittingOn1[e.ItemIndex].hasFired)
                e.Graphics.DrawImage(EEGraphics.unitFired, new Point(e.Bounds.Left + 10, e.Bounds.Top + PlayingPieceGraphics.GetBlockSize().Height / 2));
        }

        private void attackerGSUListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintGSU(e.Graphics, attackerGSUList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), false);
        }

        private void defenderGSUListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintGSU(e.Graphics, defenderGSUList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), false);
        }

        private void CombatDialog_Paint(object sender, PaintEventArgs e)
        {
            Point midAttackingArmor = new Point(attackingArmorGroupBox.Location.X + attackingArmorGroupBox.Size.Width / 2, attackingArmorGroupBox.Bounds.Bottom);
            Point midDefendingArmor = new Point(defendingArmorGroupBox.Location.X + defendingArmorGroupBox.Size.Width / 2, defendingArmorGroupBox.Location.Y);
            Point midAttackingInfantry = new Point(attackingInfantryGroupBox.Location.X + attackingInfantryGroupBox.Size.Width / 2, attackingArmorGroupBox.Bounds.Bottom);
            Point midDefendingInfantry = new Point(defendingInfantryGroupBox.Location.X + defendingInfantryGroupBox.Size.Width / 2 + 30, defendingInfantryGroupBox.Location.Y);

            Point midAttackingArmorOffset = new Point(midAttackingArmor.X + 30, midAttackingArmor.Y);
            Point midDefendingArmorOffset = new Point(midDefendingArmor.X + 30, midDefendingArmor.Y);
            Point midAttackingInfantryOffset = new Point(midAttackingInfantry.X + 30, midAttackingInfantry.Y);
            Point midDefendingInfantryOffset = new Point(midDefendingInfantry.X + 30, midDefendingInfantry.Y);

            int gap = defendingArmorGroupBox.Bounds.Top - attackingArmorGroupBox.Bounds.Bottom;

            if(shownForAttacker)
            {
                if (armorHittingInfantry)
                {
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), midAttackingArmor, new Point(midAttackingArmor.X, midAttackingArmor.Y + (gap / 2)));
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), new Point(midAttackingArmor.X, midAttackingArmor.Y + (gap / 2)), new Point(midDefendingInfantry.X, midAttackingInfantry.Y + (gap / 2)));
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midDefendingInfantry.X, midAttackingInfantry.Y + (gap / 2)), midDefendingInfantry, Color.Red, true, false);
                }
                else if (armorHittingArmor)
                    PlayingPieceGraphics.PaintArrow(e.Graphics, midAttackingArmor, midDefendingArmor, Color.Red, true, false);

                if (infantryHittingArmor)
                {
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), midAttackingInfantryOffset, new Point(midAttackingInfantryOffset.X, midAttackingInfantryOffset.Y + (gap / 2)));
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), new Point(midAttackingInfantryOffset.X, midAttackingInfantryOffset.Y + (gap / 2)), new Point(midAttackingArmorOffset.X, midAttackingArmorOffset.Y + (gap / 2)));
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midAttackingArmorOffset.X, midAttackingArmorOffset.Y + (gap / 2)), midDefendingArmorOffset, Color.Red, true, false);
                }
                else if (infantryHittingInfantry)
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midDefendingInfantryOffset.X, midAttackingInfantryOffset.Y), midDefendingInfantryOffset, Color.Red, true, false);
            }
            else
            {
                if (armorHittingInfantry)
                {
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), midDefendingArmor, new Point(midDefendingArmor.X, midDefendingArmor.Y - (gap / 2)));
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), new Point(midDefendingArmor.X, midDefendingArmor.Y - (gap / 2)), new Point(midAttackingInfantry.X - 20, midDefendingInfantry.Y - (gap / 2)));
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midAttackingInfantry.X - 20, midDefendingInfantry.Y - (gap / 2)), new Point(midAttackingInfantry.X - 20, midAttackingInfantry.Y), Color.Red, true, false);                    
                }
                else if (armorHittingArmor)
                    PlayingPieceGraphics.PaintArrow(e.Graphics, midDefendingArmor, midAttackingArmor, Color.Red, true, false);

                if (infantryHittingArmor)
                {
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), midDefendingInfantryOffset, new Point(midDefendingInfantryOffset.X, midDefendingInfantryOffset.Y - (gap / 2)));
                    e.Graphics.DrawLine(new Pen(Color.Red, 3F), new Point(midDefendingInfantryOffset.X, midDefendingInfantryOffset.Y - (gap / 2)), new Point(midDefendingArmorOffset.X, midDefendingArmorOffset.Y - (gap / 2)));
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midDefendingArmorOffset.X, midDefendingArmorOffset.Y - (gap / 2)), midAttackingArmorOffset, Color.Red, true, false);
                }
                else if (infantryHittingInfantry)
                    PlayingPieceGraphics.PaintArrow(e.Graphics, new Point(midAttackingInfantryOffset.X, midDefendingInfantryOffset.Y), midAttackingInfantryOffset, Color.Red, true, false);
            }
        }

        private void DoOK()
        {
            if (shownForAttacker)
            {
                foreach (BlockInfo blockInfo in attackerBlockList)
                {
                    if (!blockInfo.hasFired)
                    {
                        MessageBox.Show("All blocks must have fired before continuing...");
                        return;
                    }
                }
            }
            else
            {
                foreach (BlockInfo blockInfo in defenderBlockList)
                {
                    if (!blockInfo.hasFired)
                    {
                        MessageBox.Show("All blocks must have fired before continuing...");
                        return;
                    }
                }
            }
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            DoOK();
        }

        private enum HitGrouping
        {
            armorHittingOn1,
            armorHittingOn2,
            armorHittingOn3,
            armorHittingOn4,
            armorHittingOn5,
            armorHittingOn6,
            infantryHittingOn1,
            infantryHittingOn2,
            infantryHittingOn3,
            infantryHittingOn4,
            infantryHittingOn5,
            infantryHittingOn6,
        }

        private void DoFireAll()
        {
            Dictionary<HitGrouping, double> halfRolls = new Dictionary<HitGrouping, double>();

            foreach (HitGrouping hitGrouping in Enum.GetValues(typeof(HitGrouping)))
            {
                halfRolls.Add(hitGrouping, 0);
            }

            List<BlockInfo> listOfBlocksToFire = shownForAttacker ? attackerBlockList : defenderBlockList;
            foreach (BlockInfo blockInfo in listOfBlocksToFire)
            {
                if (!blockInfo.hasFired)
                {
                    double parthit = 0;
                    HitGrouping hitGroupingToCheck = HitGrouping.armorHittingOn1;
                    if (blockInfo.block.IsArmorClass())
                    {
                        if (armorHittingOn1.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 1;
                            hitGroupingToCheck = HitGrouping.armorHittingOn1;
                        }
                        else if (armorHittingOn2.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 2;
                            hitGroupingToCheck = HitGrouping.armorHittingOn2;
                        }
                        else if (armorHittingOn3.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 3;
                            hitGroupingToCheck = HitGrouping.armorHittingOn3;
                        }
                        else if (armorHittingOn4.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 4;
                            hitGroupingToCheck = HitGrouping.armorHittingOn4;
                        }
                        else if (armorHittingOn5.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 5;
                            hitGroupingToCheck = HitGrouping.armorHittingOn5;
                        }
                        else if (armorHittingOn6.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 6;
                            hitGroupingToCheck = HitGrouping.armorHittingOn6;
                        }
                        else
                            throw new InvalidOperationException("blockinfo not part of a grouping");
                    }
                    else
                    {
                        if (infantryHittingOn1.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 1;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn1;
                        }
                        else if (infantryHittingOn2.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 2;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn2;
                        }
                        else if (infantryHittingOn3.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 3;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn3;
                        }
                        else if (infantryHittingOn4.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 4;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn4;
                        }
                        else if (infantryHittingOn5.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 5;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn5;
                        }
                        else if (infantryHittingOn6.Contains(blockInfo))
                        {
                            blockInfo.hittingOn = 6;
                            hitGroupingToCheck = HitGrouping.infantryHittingOn6;
                        }
                        else
                            throw new InvalidOperationException("blockinfo not part of a grouping");
                    }

                    parthit = halfRolls[hitGroupingToCheck];
                    FireUnit(blockInfo, ref parthit);
                    halfRolls[hitGroupingToCheck] = parthit;
                }
            }

            SetupBlocksByHittingPowerAndClass();
            this.Invalidate();
        }

        private void fireAllUnitsButton_Click(object sender, EventArgs e)
        {
            DoFireAll();
        }

        private void CombatDialog_Shown(object sender, EventArgs e)
        {
            this.battleIcons.SetBattleIconVisibility();
        }

        private void eyeButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void CombatDialog_KeyUp(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter)
            {
                DoFireAll();
            }
            else if(e.KeyCode == Keys.Space)
            {
                DoOK();
            }
        }
    }
}